package com.ronglian.ucdisk.share.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import aj.org.objectweb.asm.Type;

import com.ronglian.ucdisk.share.ShareEvent;
import com.ronglian.ucdisk.share.ShareNodeEntity;
import com.ronglian.ucdisk.share.ShareReceiverEntity;
import com.ronglian.ucdisk.share.service.ShareService;

@Repository(value="ShareServiceImpl")
public class ShareServiceImpl implements ShareService {

	
	@PersistenceContext 
	public EntityManager em;
	@Transactional
	public void createShare(ShareEvent shareEvent) {
		// TODO Auto-generated method stub
		shareEvent.buildList() ; 
		em.persist(shareEvent);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	public long mySharesTotalCount(String userId) {
		TypedQuery<Long> qry = em.createQuery("select count(o) from ShareEvent o where o.senderId = :senderId", Long.class);
		qry.setParameter("senderId", userId); 
		long count = qry.getSingleResult();
		return count;
	}
	@Transactional(propagation=Propagation.REQUIRED)
	public List<ShareEvent> myShares(String userId, int pageSize, int pageNumber) {
		TypedQuery<ShareEvent> qry = em.createQuery("select o from ShareEvent o where o.senderId = :senderId", ShareEvent.class);
		qry.setParameter("senderId", userId);
		qry.setMaxResults(pageSize);
		qry.setFirstResult(pageSize * ( pageNumber -1 ) )  ;
		List<ShareEvent> events = qry.getResultList();
		// build nodeList . id and name 
		for(ShareEvent event:events) {
			event.buildResponseNodeList() ;
			event.buildResponseReceiverList(); 
			event.buildResponseReceiverTeamList();
		}
		return events;
	
	}

	@Transactional
	public void omitSend(String shareId) {
		// TODO Auto-generated method stub
		ShareEvent event = em.find(ShareEvent.class, shareId) ; 
		if(event == null ) return ; 
		event.status = "omit" ; 
	}


	@Transactional
	public void deleteSend(String shareId) {
		ShareEvent event = em.find(ShareEvent.class, shareId);
		if(event == null) return;
		em.remove(event); //级联删除  
	}
	
	

	@Transactional
	public void deleteNode(String shareId, String nodeId) {
		//orphan removal
		ShareEvent event = em.find(ShareEvent.class, shareId); 
		if(event == null ) {
			return; 
		}
		List<ShareNodeEntity> nodeList = event.getShareNodeIdList(); 
		for(int i = 0 ; i < nodeList.size()	 ; i ++  ){
			ShareNodeEntity sne = nodeList.get(i); 
			if(sne.getNodeId().equals(nodeId)) {
				nodeList.remove(i--);
			}
		}
		
		/* buggy.
 		TypedQuery<ShareNodeEntity> qry = em.createQuery("select o from ShareNodeEntity o where o.event.id = :eventId and o.nodeId = :nodeId",ShareNodeEntity.class);
		qry.setParameter("eventId", shareId);
		qry.setParameter("nodeId", nodeId);
		
		List<ShareNodeEntity> nodeList = qry.getResultList();
		for(ShareNodeEntity sne : nodeList) {
			em.remove(sne);
		}*/
		
	}

	@Transactional
	public void deleteReceiver(String shareId, String receiverId) {
		ShareEvent event = em.find(ShareEvent.class, shareId); 
		if(event == null ) {
			return; 
		}
		List<ShareReceiverEntity> recerList = event.getShareReceiverIdList(); 
		for(int i = 0 ; i < recerList.size()	 ; i ++  ){
			ShareReceiverEntity sre = recerList.get(i); 
			if(sre.getReceiverId().equals(receiverId)) {
				recerList.remove(i--);
			}
		}
	}

	@Transactional
	public void addNode(String shareId, String nodeId) {
		// TODO Auto-generated method stub
		ShareEvent event = em.find(ShareEvent.class,shareId); 
		if(event == null) return; 
		ShareNodeEntity sne = new ShareNodeEntity(); 
		sne.setId(UUID.randomUUID().toString());
		sne.setEvent(event);
		sne.setNodeId(nodeId);
		em.persist(sne);
	}

	@Transactional
	public void addReceiver(String shareId, String receiverId,String receiverType) {
		ShareEvent event = em.find(ShareEvent.class,shareId); 
		if(event == null) return; 
		ShareReceiverEntity sre = new ShareReceiverEntity(); 
		sre.setId(UUID.randomUUID().toString());
		sre.setEvent(event);
		sre.setReceiverId(receiverId);
		sre.setReceiverType(receiverType); 
		
		em.persist(sre);
		
	}

	@Transactional
	public void updateShare(String shareId, String permission, Date endTime) {
		ShareEvent event = em.find(ShareEvent.class,shareId) ; 
		if(event == null) return; 
		event.permission = permission; 
		event.endTime = endTime;
	}

	@Transactional(propagation=Propagation.REQUIRED)
	public long sharesToMeTotalCount(String userId) {
		TypedQuery<Long> qry = em.createQuery("select count(o) from ShareEvent o JOIN o.shareReceiverIdList shareReceiver where shareReceiver.receiverId = :userId", Long.class);
		qry.setParameter("userId", userId); 
		long count = qry.getSingleResult();
		return count;
	}
	@Transactional
	public List<ShareEvent> sharesToMe(String userId, int pageSize,
			int pageNumber) {
		TypedQuery<ShareEvent> qry = em.createQuery("select o from ShareEvent o JOIN o.shareReceiverIdList shareReceiver where shareReceiver.receiverId = :userId " ,ShareEvent.class) ;
		qry.setParameter("userId", userId);
		qry.setMaxResults(pageSize); 
		qry.setFirstResult(pageSize * (pageNumber - 1 )) ; 
		
		List<ShareEvent> events = qry.getResultList(); 
		for(ShareEvent event:events){
			event.buildResponseNodeList(); 
			event.buildResponseReceiverList(); 
			event.buildResponseReceiverTeamList();
		}
		return events;
	}

	@Transactional
	public void omitRecv(String userId, String shareId) {
		TypedQuery<ShareReceiverEntity> qry = em.createQuery("select o from ShareReceiverEntity o where o.receiverId = :userId and o.shareEventId =:shareId " ,ShareReceiverEntity.class)  ;
		qry.setParameter("userId", userId) ;
		qry.setParameter("shareId", shareId);  
		
		ShareReceiverEntity entity = qry.getSingleResult() ; 
		em.remove(entity);
	}

	@Transactional
	public void reShare(String shareId, String newReceiverId,String type) {
		//目前做法就是  直接在 原来的 列表中 加人 
		ShareEvent event = em.find(ShareEvent.class, shareId); 
		if(event == null) return; 
		
		ShareReceiverEntity entity = new ShareReceiverEntity() ; 
		entity.setEvent(event); 
		
		entity.setReceiverId(newReceiverId);
		entity.setReceiverType(type); 
		
		em.persist(entity);
	}
	@Transactional
	public ShareEvent getShareDetail(String shareId) {
		ShareEvent event = em.find(ShareEvent.class, shareId) ;
		if(event == null) return null;
		//获取列表信息
		List<ShareNodeEntity> nodeList = event.getShareNodeIdList() ; 
		if(nodeList!=null) {for(ShareNodeEntity sne : nodeList){
			String nodeId = sne.getNodeId() ;
			
			TypedQuery<String> qry = em.createQuery("select o.name from Node o where o.id = :id" , String.class);
			qry.setParameter("id", nodeId);
			
			String name  = null ; 
			try{
				name = qry.getSingleResult() ;
			}catch(Exception e) {
				
			}
			event.addResponseNodeInfo(nodeId, name);
		}}
		
		List<ShareReceiverEntity>  receiverList = event.getShareReceiverIdList();
		if (receiverList != null) {
			for (ShareReceiverEntity sre : receiverList) {
				String id = sre.getReceiverId();
				String name = null;
				try {
					if (sre.isSingle()) {
						name = em
								.createQuery(
										"select o.workNum from UserAccount o where o.id = :id",
										String.class).setParameter("id", id)
								.getSingleResult();
						event.addResponseReceiverInfo(id, name);
					} else {
						name = em
								.createQuery(
										"select o.name from TeamInfo o where o.id = :id",
										String.class).setParameter("id", id)
								.getSingleResult();
						event.addResponseReceiverTeamInfo(id, name);
					}
				} catch (Exception e) {

				}
		}}
		return event;
	}
	
	/*
	 
	 public EntityManager entityManager() {
		 //相当于在这里进行 EntityManager的注入
		 	if(emFac==null) {
		 		emFac = (EntityManagerFactory)App.ctx.getBean("entityManagerFactory");
		 	}
	        EntityManager em =  emFac.createEntityManager();
	        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
	        return em;
	 }
	 // 这个函数跟 roo 生成的函数不太一致 
	 public ShareEvent findShareEvent(String id) {
		 if(id == null || id.length()  == 0 ) return null; 
		 if(this.entityManager == null ) this.entityManager = entityManager() ; 
		 
		 return this.entityManager.find(ShareEvent.class, id);
	 }
	 @Transactional 
	 public void persist(){	
		  if(this.entityManager == null ) this.entityManager = entityManager() ;
		  this.entityManager.persist(this);
		  
	 }
	 
	 @Transactional 
	 public void remove() {
		 if(this.entityManager == null ) this.entityManager = entityManager();
		 if(this.entityManager.contains(this)) {
			 this.entityManager.remove(this);
		 }else {
			 ShareEvent attached = findShareEvent(this.id); 
			 this.entityManager.remove(attached);
		 }
	 }
	 */

}
